package com.myk.game.gobangchess.rooms;

import com.myk.game.gobangchess.CustomBottom;
import com.myk.game.gobangchess.DataManager;
import com.myk.game.gobangchess.Player;
import com.myk.game.gobangchess.Sign;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.rooms.absrooms.AbsDiffViewChessRoom;
import com.myk.game.gobangchess.signs.*;
import com.myk.game.gobangchess.utils.GridsUtils;
import com.myk.game.gobangchess.utils.Pair;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;


/**
 * 幽灵棋 又名好鬼难寻
 */
public class GhostsRoom extends AbsDiffViewChessRoom {

    private List<Sign> chessboardStyle; //不变的棋盘样式
    private Integer[] blackExitIds, whiteExitIds;//双方出口格子索引
    private Integer[] blackBirthIds, whiteBirthIds;//双方出生点格子索引

    private List<Ghost> chessList; //场上棋子集合
    private Ghost choose; //当前选中的棋子
    private int[] moveArrow;//移动箭头状态
    private Ghost blackSwapTarget, whiteSwapTarget; //布局阶段持有的选中交换棋子
    private boolean blackDisplayFlag, whiteDisplayFlag; //布局状态，布局完成转为true

    public GhostsRoom(String roomName) {
        super(roomName, "幽灵棋又名好鬼难寻，一款双人心理博弈棋。", "幽灵棋", GridsUtils.createEmptyGrids(6, 6), false, true);
        initChessboardStyle();
    }

    @Override
    public String getRuleText() {
        return "《幽灵棋》游戏规则\n" +
                "6*6格子棋盘,\n" +
                "两种棋子，蓝眼睛的好鬼和红眼睛的坏鬼,\n" +
                "双方每人有4个好鬼和4个坏鬼。 \n" +
                "开局布阵时，在靠近自己的一边摆上两排鬼，每排四个。棋盘的最左边和最右边不能摆子。好坏鬼的顺序可以自由排列。\n" +
                "每一回合一个人可以移动一个鬼走一格，不能原地不动，不能移动到自己鬼所在的格子上，移动到对方的鬼上可以吃掉。\n" +
                "鬼除了被吃，双方都不能看到对方的鬼是好鬼还是坏鬼。棋盘底部显示的是双方剩余鬼的数量。\n"+
                //"靠近对方一行的两个后门是自己方的出口，好鬼移动到出口算逃出。\n" +
                "靠近对方一行的两个后门是自己方的出口，好鬼移动到出口后再原地走一步算逃出。\n" +
                "三种胜利条件：\n" +
                "1、你的好鬼从后门逃出了；\n" +
                "2、你吃掉了对方四个好鬼；\n" +
                "3、你的四个坏鬼被对方吃掉；";
    }

    //定义棋盘样式
    private void initChessboardStyle() {
        int row = curGrids.length;
        int col = curGrids[0].length;
        chessboardStyle = new ArrayList<>();
        blackExitIds = new Integer[]{0, 5};
        whiteExitIds = new Integer[]{30, 35};
        blackBirthIds = new Integer[]{1, 2, 3, 4, 7, 8, 9, 10};
        whiteBirthIds = new Integer[]{25, 26, 27, 28, 31, 32, 33, 34};
        //绘制格子颜色
        List<Integer> allIds = new ArrayList<>();
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                allIds.add(getIndex(i, j));
            }
        }
        List<Integer> exitIds = new ArrayList<>();
        exitIds.addAll(Arrays.asList(blackExitIds));
        exitIds.addAll(Arrays.asList(whiteExitIds));
        chessboardStyle.add(new ColorSign(allIds, "#FF186597")); //深蓝色
        chessboardStyle.add(new ColorSign(exitIds, "#FF5DC7E7")); //浅蓝色
        //绘制图纹
        FigureSign figure = FigureSign.makeBatchSingleFigure(allIds, "#66002288");
        figure.setAdjMidLine(1, 1, 1, 1);
        figure.setCorCenLine(1, 1, 1, 1);
        chessboardStyle.add(figure);
        //绘制格子线
        for (int i = 1; i < row; i++) {
            List<Pair<Integer, Integer>> nodes1 = new ArrayList<>();
            nodes1.add(new Pair<>(getIndex(i, 0), 0)); //起点
            nodes1.add(new Pair<>(getIndex(i, col - 1), 2)); //终点
            chessboardStyle.add(new PathSign(nodes1, "#FF001122", "#00000000", 2f, 0));
        }
        for (int j = 1; j < col; j++) {
            List<Pair<Integer, Integer>> nodes1 = new ArrayList<>();
            nodes1.add(new Pair<>(getIndex(0, j), 0)); //起点
            nodes1.add(new Pair<>(getIndex(row - 1, j), 6)); //终点
            chessboardStyle.add(new PathSign(nodes1, "#FF001122", "#00000000", 2f, 0));
        }
        //绘制大外边框
        chessboardStyle.add(new GroundSign(getIndex(0, 0), getIndex(row - 1, col - 1), "#005DC7E7", "#FF001122", 4f, 0, 0)); //外边框
    }

    @Override
    public String getGameInfo(int viewPoint) {
        curGrids = GridsUtils.copyGrids(originGrids);
        signList.clear();
        signList.addAll(chessboardStyle);
        //绘制出口箭头
        String leftArr = "\uD83D\uDC48"; //emoji字符食指向左
        String rightArr = "\uD83D\uDC49"; //emoji字符食指向右边
        String exitArrColor = "#FFF0A423"; //出口箭头金色
        TextSign a, b, c, d;
        signList.add(a = new TextSign(blackExitIds[0], leftArr, exitArrColor));
        signList.add(b = new TextSign(blackExitIds[1], rightArr, exitArrColor));
        signList.add(c = new TextSign(whiteExitIds[0], leftArr, exitArrColor));
        signList.add(d = new TextSign(whiteExitIds[1], rightArr, exitArrColor));

        //绘制棋子和状态
        if (chessList != null && chessList.size() > 0) {
            //绘制棋子
            for (Ghost chess : chessList) {
                curGrids[chess.pRow][chess.pCol] = chess.mSide; //显示棋子的底座 双方都是白色棋子
                if (viewPoint == chess.mSide || viewPoint == 3) { //只能看自己的好鬼坏鬼样式，或者终局时所有人都能看到
                    signList.add(new TitleSign((chess.pCol + 0.5f) / curGrids[0].length, (chess.pRow + 0.4f) / curGrids.length, 0, "0 0", chess.getFrontColor(), 0.3f));
                }
                else {
                    signList.add(new TitleSign((chess.pCol + 0.5f) / curGrids[0].length, (chess.pRow + 0.4f) / curGrids.length, 0, "0 0", chess.getBackColor(), 0.3f));
                }
            }

            //有棋子的出口就不要显示手指了
            int row = curGrids.length;
            int col = curGrids[0].length;
            if (curGrids[0][0] != 0) {
                signList.remove(a);
            }
            if (curGrids[0][col - 1] != 0) {
                signList.remove(b);
            }
            if (curGrids[row - 1][0] != 0) {
                signList.remove(c);
            }
            if (curGrids[row - 1][col - 1] != 0) {
                signList.remove(d);
            }

            //绘制双方剩余好鬼坏鬼数量，棋盘底部内边距有一些空间，底部左半边显示黑方，右半边显示白方，蓝色和红色单夹形式。 ⚇⚇⚇⚇⚇⚇⚇⚇          ⚉⚉⚉⚉⚉⚉⚉⚉
            int blackGoodCount = getGhostsCount(1, 0);
            int blackBadCount = getGhostsCount(1, 1);
            int whiteGoodCount = getGhostsCount(2, 0);
            int whiteBadCount = getGhostsCount(2, 1);
            float bGClipX = (0 + 0.5f) / curGrids[0].length;
            float bBClipX = (1 + 0.5f) / curGrids[0].length;
            float wGClipX = (curGrids[0].length - 1 + 0.5f) / curGrids[0].length;
            float wBClipX = (curGrids[0].length - 2 + 0.5f) / curGrids[0].length;
            float aClipY = (curGrids.length + 0.2f) / curGrids.length;
            StringBuilder bGStr = new StringBuilder();
            for (int i = 0; i < blackGoodCount; i++) {
                bGStr.append("⚉");
            }
            signList.add(new TitleSign(bGClipX, aClipY, 0, bGStr.toString(), "#FF5588FF", 0.3f));
            StringBuilder bBStr = new StringBuilder();
            for (int i = 0; i < blackBadCount; i++) {
                bBStr.append("⚉");
            }
            signList.add(new TitleSign(bBClipX, aClipY, 0, bBStr.toString(), "#FFFF5588", 0.3f));
            StringBuilder wGStr = new StringBuilder();
            for (int i = 0; i < whiteGoodCount; i++) {
                wGStr.append("⚇");
            }
            signList.add(new TitleSign(wGClipX, aClipY, 0, wGStr.toString(), "#FF5588FF", 0.3f));
            StringBuilder wBStr = new StringBuilder();
            for (int i = 0; i < whiteBadCount; i++) {
                wBStr.append("⚇");
            }
            signList.add(new TitleSign(wBClipX, aClipY, 0, wBStr.toString(), "#FFFF5588", 0.3f));

            //绘制对弈时的选中棋子移动状态
            if (choose != null && choose.mSide == viewPoint) {
                List<int[]> canMovedPosList = choose.getCanMovedPos(this, curGrids); //获取该棋子可移动到的格子的坐标集合
                if (canMovedPosList.size() > 0) {
                    List<Integer> ids = new ArrayList<>();
                    for (int[] canMovedPos : canMovedPosList) {
                        ids.add(getIndex(canMovedPos[0], canMovedPos[1]));
                    }
                    signList.add(new ColorSign(ids, "#9988EE88")); //可移动到的格子用更淡的绿色表示
                }
                //绘制棋子选中状态
                signList.add(new GroundSign(getIndex(choose.pRow, choose.pCol), "#00FFFFFF", "#FF33CC33", 2F, 0, 1));
            }

            //绘制对弈时的箭头标记
            if (moveArrow != null && moveArrow.length == 2) {
                signList.add(new LineSign(moveArrow[0], moveArrow[1], "#9933CC33", 1));
            }

            //绘制布局时的选中状态
            if (viewPoint == 1 && !blackDisplayFlag && blackSwapTarget != null) {
                List<Integer> ins = new ArrayList<>();
                ins.add(getIndex(blackSwapTarget.pRow, blackSwapTarget.pCol));
                signList.add(new AroundSign(ins, "#00FFFFFF", "#FF33AA33", 1.5f));
            }
            if (viewPoint == 2 && !whiteDisplayFlag && whiteSwapTarget != null) {
                List<Integer> ins = new ArrayList<>();
                ins.add(getIndex(whiteSwapTarget.pRow, whiteSwapTarget.pCol));
                signList.add(new AroundSign(ins, "#00FFFFFF", "#FF33AA33", 1.5f));
            }


        }

        return super.getGameInfo();
    }

    @Override
    public String getCoordMode() {
        return "00000000";
    }

    public int getGhostsCount(int side, int type) {
        int count = 0;
        for (Ghost ghost : chessList) {
            if (ghost.mSide == side && ghost.type == type) {
                count++;
            }
        }
        return count;
    }

    @Override
    protected void onStartPrepare() {
        initChessList();//游戏开始的时候初始化棋子和布局
        initStartCustoms();//分发布局状态按钮
        noticeAllMove(); //开局双方先随机布局
        noticeAllBroadcast("请双方调整初始阵形，修改完成后请点击[布局完成]");
    }

    private void initChessList() {
        chessList = new ArrayList<>();
        initBlackChessList();
        initWhiteChessList();
    }

    private void initBlackChessList() {
        blackSwapTarget = null;
        chessList.removeIf(ghost -> ghost.mSide == 1);
        List<Ghost> temps = new ArrayList<>();
        temps.add(new Ghost(1, 0, 0, 0));
        temps.add(new Ghost(1, 0, 0, 0));
        temps.add(new Ghost(1, 0, 0, 0));
        temps.add(new Ghost(1, 0, 0, 0));
        temps.add(new Ghost(1, 1, 0, 0));
        temps.add(new Ghost(1, 1, 0, 0));
        temps.add(new Ghost(1, 1, 0, 0));
        temps.add(new Ghost(1, 1, 0, 0));
        Collections.shuffle(temps);
        for (int i = 0; i < temps.size(); i++) {
            Ghost chess = temps.get(i);
            int index = blackBirthIds[i];
            int width = curGrids[0].length;
            chess.pRow = index / width;
            chess.pCol = index % width;
        }
        chessList.addAll(temps); //最后再放到公共的棋子容器里
    }

    private void initWhiteChessList() {
        whiteSwapTarget = null;
        chessList.removeIf(ghost -> ghost.mSide == 2);
        List<Ghost> temps = new ArrayList<>();
        temps.add(new Ghost(2, 0, 0, 0));
        temps.add(new Ghost(2, 0, 0, 0));
        temps.add(new Ghost(2, 0, 0, 0));
        temps.add(new Ghost(2, 0, 0, 0));
        temps.add(new Ghost(2, 1, 0, 0));
        temps.add(new Ghost(2, 1, 0, 0));
        temps.add(new Ghost(2, 1, 0, 0));
        temps.add(new Ghost(2, 1, 0, 0));
        Collections.shuffle(temps);
        for (int i = 0; i < temps.size(); i++) {
            Ghost chess = temps.get(i);
            int index = whiteBirthIds[i];
            int width = curGrids[0].length;
            chess.pRow = index / width;
            chess.pCol = index % width;
        }
        chessList.addAll(temps); //最后再放到公共的棋子容器里
    }

    @Override
    public void moveLater(Player player, int row, int col) {
        if (player_black != null && player_white != null && player_black == player_white) { //个人模式下
            if (cur == 1) {
                doRule(row, col, 1);
            }
            else if (cur == 2) {
                doRule(row, col, 2);
            }
            else if (cur == 3) { //自由布局阶段
                Ghost chess = getChessByPos(row, col); //根据你触摸到的棋子来替换
                if (chess != null) {
                    if (chess.mSide == 1) {
                        doRule(row, col, 1);
                    }
                    else if (chess.mSide == 2) {
                        doRule(row, col, 2);
                    }
                }
            }
        }
        else {//双人模式下
            if (player_black == player) {
                if (cur == 1 || cur == 3) { //3是双方都在自由布局时的阶段
                    doRule(row, col, 1);
                }
            }
            if (player_white == player) {
                if (cur == 2 || cur == 3) {//3是双方都在自由布局时的阶段
                    doRule(row, col, 2);
                }
            }
        }
    }

    private Ghost getChessByPos(int row, int col) {
        for (Ghost chess : chessList) {
            if (chess.pRow == row && chess.pCol == col) {
                return chess;
            }
        }
        return null;
    }

    @Override
    public void resetGrids() {
        step = 0;
        gameTip = "-1";
        curGrids = GridsUtils.copyGrids(originGrids);
        signList.clear();
        chessList = null;
        choose = null;
        moveArrow = null;
        blackSwapTarget = null;
        whiteSwapTarget = null;
        blackDisplayFlag = false;
        whiteDisplayFlag = false;
    }

    private void initStartCustoms() {
        if (player_black != null && player_white != null && player_black == player_white) { //个人模式下发按钮的逻辑
            player_black.registerCustomBottom(
                    new CustomBottom(this, "随机布局", player -> {
                        initChessList();//再重新生成布局
                        noticeAllRefreshGameInfo();//通知界面刷新
                    }),
                    new CustomBottom(this, "布局完成", player -> {
                        //单人模式不需要交换规则直接就通知开始
                        initChessList();
                        noticeAllBroadcast("布局完成可选择棋子移动");
                        player_black.clearCustomBottom();
                        player_black.dispatchCustomBottom();
                        noticeBlackMove(); //然后黑方先手落子
                    })
            );
        }
        else { //双人模式下发按钮的逻辑
            if (player_black != null) {
                player_black.registerCustomBottom(
                        new CustomBottom(this, "随机布局", player -> {
                            initBlackChessList();//再重新生成布局
                            noticeAllRefreshGameInfo();//通知界面刷新
                        }),
                        new CustomBottom(this, "布局完成", player -> {
                            //黑方布局完成就暂停操作
                            blackSwapTarget = null;
                            blackDisplayFlag = true;
                            player_black.clearCustomBottom();
                            player_black.dispatchCustomBottom();
                            //判断白方是否也布局完成了
                            if (whiteDisplayFlag) {
                                noticeAllBroadcast("黑方开始选择棋子移动");
                                player_white.clearCustomBottom();
                                player_white.dispatchCustomBottom();
                                noticeBlackMove();
                            }
                            else {
                                noticeWhiteMove(); //白方继续能修改棋子位置
                            }
                        })
                );
            }
            if (player_white != null) {
                player_white.registerCustomBottom(
                        new CustomBottom(this, "随机布局", player -> {
                            initWhiteChessList();//再重新生成布局
                            noticeAllRefreshGameInfo();//通知界面刷新
                        }),
                        new CustomBottom(this, "布局完成", player -> {
                            whiteSwapTarget = null;
                            whiteDisplayFlag = true;
                            player_white.clearCustomBottom();
                            player_white.dispatchCustomBottom();
                            if (blackDisplayFlag) {
                                noticeAllBroadcast("黑方开始选择棋子移动");
                                player_white.clearCustomBottom();
                                player_white.dispatchCustomBottom();
                                noticeBlackMove();
                            }
                            else {
                                noticeBlackMove();
                            }
                        })
                );
            }
        }
    }

    @Override
    public void doRule(int row, int col, int value) {
        if (!blackDisplayFlag && value == 1) {//黑方修改棋子位置
            if (curGrids[row][col] == value){
                swapBlackChess(getChessByPos(row, col));
                noticeAllRefreshGameInfo();
            }
        }
        else if (!whiteDisplayFlag && value == 2) {//白方修改棋子位置
            if (curGrids[row][col] == value){
                swapWhiteChess(getChessByPos(row, col));
                noticeAllRefreshGameInfo();
            }
        }
        else {//正常对弈时
            if (value == 1) { //黑方点击
                Ghost chess = getChessByPos(row, col); //目标是否有棋子
                if (choose == null || choose.mSide != 1) { //黑方还未选择目标时
                    if (chess != null && chess.mSide == 1) { //触摸到棋子且是黑方
                        moveArrow = null; //以免标记太多碍眼
                        choose = chess;//选中己方棋子
                        noticeAllRefreshGameInfo(); //仅仅刷新显示，黑方还能继续点击
                    }
                }
                else { //已经选中黑方棋子了
                    if (choose.isPosCanMove(row, col, this, chess)) { //目标位置可以移动到
                        //移动判定
                        if (choose.type == 0 && choose.pRow == row && choose.pCol == col) { //检测是否逃离(只有好鬼处于对面出口才有可能原地走)
                            doChessMove(row, col);//执行移动操作
                            doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "好鬼从后门逃走获胜！");
                        }
//                        if (choose.type == 0 && isIntoExit(choose, getIndex(row, col))){ //检测好鬼是否走到了出口
//                            doChessMove(row, col);//执行移动操作
//                            doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "好鬼从后门逃走获胜！");
//                        }
                        else {
                            if (chess != null) {//吃子判定
                                doChessMove(row, col);//执行移动操作
                                chessList.remove(chess); //暂时先从列表中移除，避免判定和绘制干扰
                                int whiteGoodCount = getGhostsCount(2, 0);
                                if (whiteGoodCount == 0) {
                                    doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "吃光对方好鬼获胜！");
                                    return;
                                }
                                int whiteBadCount = getGhostsCount(2, 1);
                                if (whiteBadCount == 0) {
                                    doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "坏鬼被吃光获胜！");
                                    return;
                                }
                                noticeWhiteMove();
                            }
                            else { //普通移动
                                doChessMove(row, col);//执行移动操作
                                noticeWhiteMove();
                            }
                        }
                    }
                    else { //目标位置不能移动到
                        if (chess != null && chess.mSide == 1) { //点到自己其它棋子切换选中
                            choose = chess;//切换选中己方棋子
                            noticeAllRefreshGameInfo(); //仅仅刷新显示，还能继续点击
                        }
                        else { //点到其它地方取消选中
                            choose = null;
                            noticeAllRefreshGameInfo(); //仅仅刷新显示，还能继续点击
                        }
                    }
                }

            }

            else if (value == 2) { //白方点击
                Ghost chess = getChessByPos(row, col); //目标是否有棋子
                if (choose == null || choose.mSide != 2) { //白方还未选择目标时
                    if (chess != null && chess.mSide == 2) { //触摸到棋子且是白方
                        moveArrow = null; //以免标记太多碍眼
                        choose = chess;//选中己方棋子
                        noticeAllRefreshGameInfo(); //仅仅刷新显示，还能继续点击
                    }
                }
                else { //已经选中白方棋子了
                    if (choose.isPosCanMove(row, col, this, chess)) { //目标位置可以移动到
                        //移动判定
                        if (choose.type == 0 && choose.pRow == row && choose.pCol == col) { //检测是否进入对方禁区
                            doChessMove(row, col);//执行移动操作
                            doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "好鬼从后门逃走获胜！");
                        }
//                        if (choose.type == 0 && isIntoExit(choose, getIndex(row, col))){
//                            doChessMove(row, col);//执行移动操作
//                            doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "好鬼从后门逃走获胜！");
//                        }
                        else {
                            if (chess != null) {//吃子判定
                                doChessMove(row, col);//执行移动操作
                                chessList.remove(chess); //暂时先从列表中移除，避免判定和绘制干扰
                                int blackGoodCount = getGhostsCount(1, 0);
                                if (blackGoodCount == 0) {
                                    doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "吃光对方好鬼获胜！");
                                    return;
                                }
                                int blackBadCount = getGhostsCount(1, 1);
                                if (blackBadCount == 0) {
                                    doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "坏鬼被吃光获胜！");
                                    return;
                                }
                                noticeBlackMove();
                            }
                            else { //普通移动
                                doChessMove(row, col);//执行移动操作
                                noticeBlackMove();
                            }
                        }
                    }
                    else { //目标位置不能移动到
                        if (chess != null && chess.mSide == 2) { //点到自己其它棋子切换选中
                            choose = chess;//切换选中己方棋子
                            noticeAllRefreshGameInfo(); //仅仅刷新显示，还能继续点击
                        }
                        else { //点到其它地方取消选中
                            choose = null;
                            noticeAllRefreshGameInfo(); //仅仅刷新显示，还能继续点击
                        }
                    }
                }
            }
        }
    }

    private boolean isIntoExit(Ghost choose, int index) {
        if (choose.mSide == 1) {
            return whiteExitIds[0] == index || whiteExitIds[1] == index; //黑棋进入了白方那边出口
        }
        else if (choose.mSide == 2) {
            return blackExitIds[0] == index || blackExitIds[1] == index; //白棋进入了黑方那边出口
        }
        else {
            return false;
        }
    }

    private void swapBlackChess(Ghost target) {
        if (target == null) {
            return;
        }
        if (blackSwapTarget == null) {
            blackSwapTarget = target;
        }
        else {
            int tempCol = blackSwapTarget.pCol;
            int tempRow = blackSwapTarget.pRow;
            blackSwapTarget.pRow = target.pRow;
            blackSwapTarget.pCol = target.pCol;
            target.pRow = tempRow;
            target.pCol = tempCol;
            blackSwapTarget = null;
        }
    }

    private void swapWhiteChess(Ghost target) {
        if (target == null) {
            return;
        }
        if (whiteSwapTarget == null) {
            whiteSwapTarget = target;
        }
        else {
            int tempCol = whiteSwapTarget.pCol;
            int tempRow = whiteSwapTarget.pRow;
            whiteSwapTarget.pRow = target.pRow;
            whiteSwapTarget.pCol = target.pCol;
            target.pRow = tempRow;
            target.pCol = tempCol;
            whiteSwapTarget = null;
        }
    }

    //执行棋子移动操作
    private void doChessMove(int row, int col) {
        moveArrow = new int[]{getIndex(choose.pRow, choose.pCol), getIndex(row, col)};
        choose.pRow = row;
        choose.pCol = col;
        stepAdd();
        choose = null;
    }

    private static class Ghost {
        int mSide; //归属黑棋还是白棋 1黑  2白  9中立
        int type; //0好鬼  1坏鬼
        int pRow; //在棋盘上的横坐标
        int pCol; //在棋盘上的纵坐标

        public Ghost(int mSide, int type, int pRow, int pCol) {
            this.mSide = mSide;
            this.type = type;
            this.pRow = pRow;
            this.pCol = pCol;
        }

        public String getFrontColor() {
            if (type == 0) {
                return "#FF5588FF";
            }
            else {
                return "#FFFF5588";
            }
        }

        public String getBackColor() {
            if (mSide == 1) {
                return "#FFFFFFFF";
            }
            else {
                return "#FF000000";
            }

        }

        public boolean isPosCanMove(int row, int col, GhostsRoom room, Ghost hasChess) {
            if (hasChess != null && hasChess.mSide == mSide && hasChess != this) {
                return false; //不能移动到自己棋子上, 原地不动例外，原地不动后面要判断是否走到了出口
            }
            else {
                if (row == pRow && col == pCol && type == 0) {
                    return room.isIntoExit(this, room.getIndex(row, col)); //如果是好鬼处于出口，那么可以原地再走一次，用于获胜
                    //return false; //不能原地再走
                }
                else {
                    int h = Math.abs(row - pRow);
                    int w = Math.abs(col - pCol);
                    return h == 1 && w == 0 || h == 0 && w == 1; //只能直向移动一格
                }
            }
        }

        public List<int[]> getCanMovedPos(GhostsRoom room, int[][] curGrids) {
            List<int[]> canMovedPosList = new ArrayList<>();
            int h = curGrids.length;
            int w = curGrids[0].length;
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    if (isPosCanMove(i, j, room, room.getChessByPos(i, j))) {
                        canMovedPosList.add(new int[]{i, j});
                    }
                }
            }
            return canMovedPosList;
        }
    }
}
